#include <iostream>
#include <string.h>

using std::cout;
using std::endl;
using std::string;

//派生里没有拷贝构造、赋值运算符函数时，会自动调用基类的这两个
class Base{
public:
    Base()
    : _pbase(nullptr)
    {
        cout<<"Base()"<<endl;
    }
    Base(const char *pstr)
    : _pbase(new char[strlen(pstr)+1]())
    {
        strcpy(_pbase,pstr);
        cout<<"有参构造"<<endl;
    }

    Base(const Base &rhs)
    : _pbase(new char[strlen(rhs._pbase)+1]())
    {
        strcpy(_pbase,rhs._pbase);
        cout<<"拷贝构造"<<endl;
    }

    Base &operator=(const Base &rhs){
        cout<<"赋值运算符函数"<<endl;
        if(this != &rhs){
            delete []_pbase;
            _pbase=nullptr;

            _pbase=new char[strlen(rhs._pbase)+1]();
            strcpy(_pbase,rhs._pbase);
        }
        return *this;

    }

    ~Base(){
        cout<<"~Base()"<<endl;
        if(_pbase){
            delete []_pbase;
            _pbase=nullptr;
        }
    }

    friend std::ostream &operator<<(std::ostream &os, const Base &rhs);

private:
    char *_pbase;
};

std::ostream &operator<<(std::ostream &os, const Base &rhs){
    if(rhs._pbase){
        os<<rhs._pbase;
    }
    return os;
}

class Deriver
: public Base
{
public:
    Deriver(const char *pbase)
    : Base(pbase)
    {
        cout<<"Deriver()"<<endl;
    }
    ~Deriver(){
        cout<<"~Deriver()"<<endl;
    }

    //友元函数不继承，所以自己单独写一个
    friend std::ostream &operator<<(std::ostream &os, const Deriver &rhs);

};

//这和上面的base的<<，形成函数重载，因为参数列表不同
std::ostream &operator<<(std::ostream &os, const Deriver &rhs){
    const Base &ref=rhs;
    os<<ref;    //调用了Base的重载输出流
    return os;
}

void test(){
    Deriver der1("hello");
    cout<<der1<<endl;

    cout<<endl;
    Deriver der2=der1;
    cout<<der2<<endl;

    cout<<endl;
    Deriver der3("world");
    cout<<der3<<endl;

    cout<<endl;
    der3=der1;
    cout<<der1<<endl;
    cout<<der3<<endl;

    cout<<endl;
}
int main()
{   
    test();
    return 0;
}

